/*
 * To change this template, choose Tools | Templates
 * and open the taemplate in the editor.
 */
package serv;

import IA.DistFS.*;
import IA.DistFS.Servers.WrongParametersException;
import aima.search.framework.Problem;
import aima.search.framework.Search;
import aima.search.framework.SearchAgent;
import aima.util.*;
import aima.search.informed.*;
import java.util.ArrayList;
import java.util.Random;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author sendra
 */
public class Servi {

    public static int usuarios = 200; 
    public static int maxFitxers = 5;
    public static int maxServers = 50;
    public static int maxRep ;
    public static int minRepFitx = 5;
	public static int[] vSeeds = {915, 350, 463, 526, 331, 520, 843, 363, 405, 205};
    public static int seeds ;
        
    public static Requests requests;
    public static Servers servers;
    public static Estado lastState;
    public static int total_fitxers;
	
	public static int RandomMax = 100;
	
	public static boolean SortidaR = true;
	
	
	public enum Algorithm {
        HillClimbing,
        SimulatedAnnealing
        
    };
	public static Algorithm current;
		/* Annealing Params */
		public static int maxIteracions = 15000;//10000;
		public static int iteracionsPerPas = 500;//100;
		public static int k = 50;//500; //com mes gran mes triga en decreixe la funció
		public static double lambda = 10; // com mes gran mes rapid decreix la funció
		/* - - - - - - - - */
	

	public enum Escenari{
		retornatots,
		noretornatots
	};
	public static Escenari esc;

	public enum Casos{
		cas1,
		cas2
	};
	public static Casos cas;
	
	public static boolean SolucioInicialInteligent = true;
        
	
	public static void generatePeticions() throws WrongParametersException  {
		Servi.requests = new Requests( usuarios, maxFitxers, seeds );
		Servi.servers = new Servers( maxServers, minRepFitx, seeds );
		
		String out = "\tNumero de servidors: " + Servi.maxServers + "\n";
		out += "\tNumero de fitxers: " + Servi.maxFitxers + "\n";
		out += "\tNumero d'usuaris: " + Servi.usuarios + "\n";
		out += "\tSeeds: " + Servi.seeds + "\n";
		System.out.print(out);
	}
	
	public static Estado generateInitialState() {
        
		//System.out.println("\nCreo estat inicial: ");
		//System.out.println("\n==========================================================================================================================\n");
		
		Estado inicial = new Estado(maxFitxers, maxServers);
		inicial.crearEstatInicial( requests, servers );
		
		total_fitxers = inicial.calculateTotalFitxers();
		//System.out.println( inicial.toString() );
		
		return inicial;
	}
	
	public static String execute() throws Exception {

		long time1 = System.currentTimeMillis();
		
		Estado ini = Servi.generateInitialState();

		//crec k hem de tornar un estat final, don treurem totes les solucions: el temps total etc...
		Estado solucio;

		Problem problem = null;
		if( Servi.esc == Escenari.retornatots ) {
			if( Servi.current == Algorithm.HillClimbing ){
				problem = new Problem( ini, new simpleAllSuccessorFunction(), new FitxGoalTest(), new FitxHeuristicFunction()  );
			}else{
				problem = new Problem( ini, new randSimpleAllSuccessorFunction(), new FitxGoalTest(), new FitxHeuristicFunction()  );
			}
		}else{
			if( Servi.current == Algorithm.HillClimbing ){
				problem = new Problem( ini, new mediumAllSuccessorFunction(), new FitxGoalTest(), new FitxHeuristicFunction()  );
			}else{
				problem = new Problem( ini, new randMediumAllSuccessorFunction(), new FitxGoalTest(), new FitxHeuristicFunction()  );
			}
		}
		
		Search search = null;
		switch( Servi.current ) {
			case HillClimbing:
				search = new HillClimbingSearch();
				break;

			case SimulatedAnnealing:
				search = new SimulatedAnnealingSearch( Servi.maxIteracions, Servi.iteracionsPerPas, Servi.k, Servi.lambda );
				break;
		}

		SearchAgent searchAgent = new SearchAgent(problem, search);

		//a solucio hi haura lultim estat trobat, ergo la solucio: somple a simpleallsuccessorfunction
		long time2 = System.currentTimeMillis();
		solucio = (Estado) Servi.lastState;
		String out = "";
		if ( Servi.SortidaR )  out = (time2 - time1) + "\t " + (int)solucio.temps;
		else {
			System.out.println("\nSOLUCIO:\n");
			System.out.print(solucio.toString());
		}
		
		
		return out;
		//return search.getMetrics().getInt("Iterations");
		
	}
 
    
}
